using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Net;
using Microsoft.Win32;
using System.Threading;
using OdsControllerLib;
using System.Net.NetworkInformation;
using OdsController.Helpers;


namespace OdsController {
	public partial class form_main : Form {
		Thread DetectPubIPThread;
		Thread DetectServerConnectivityThread;

		public form_log FormLog;
		public form_settings FormSettings;

		/// <summary>
		/// IntPtr handle for the Toggle Log toolbar button - to support minimize animation
		/// </summary>
		public IntPtr LogButtonWhnd;
		/// <summary>
		/// IntPtr handle for the Toggle Settings toolbar button - to support minimize animation
		/// </summary>
		public IntPtr SettingsButtonWhnd;

		private const int _normalHeight = 164; // min 164 ---- max: 351
		private const int _expandedHeight = 358;


		public form_main() {
			InitializeComponent();
			this.Height = _normalHeight;
			Icon = Properties.Resources.IconAppMain;
			Text = Application.ProductName;
			_lastLocation = Location;


			// init tray icon
			notifyIcon1.Icon = Icon;
			notifyIcon1.Text = Text;
			notifyIcon1.Visible = true;

			// used by the minimizeToToolbar on forms
			LogButtonWhnd = tbsMain.Handle;
			SettingsButtonWhnd = tbsMain.Handle;
		}

		#region FormEvents
		private void NetworkAddressChanged() {
			this.LogWrite("Network address changed.", LogCategories.ApplicationEvents, DateTime.Now);

			// detect my public ip and reload myips combobox
			DetectAndReloadMyIPList();

			// check to see if we can still contact the ods update service
			DetectServerConectivity();

			// if defined by the user update all hosts
			if (MainObj.NetworkHelper.GetOnline(true) && MainObj.OdsMain.Settings.UpdateOnIPChange) {
				this.LogWrite("Updating all hosts due to network address changed event.", LogCategories.ApplicationEvents, DateTime.Now);
				UpdateAll();
			}
		}
		private void netAvailabilityChanged(bool available) {
			bool netAvailable = NetworkInterface.GetIsNetworkAvailable();
			this.LogWrite("Network availability changed: " + (netAvailable ? "networks available" : "no networks available"), LogCategories.ApplicationEvents, DateTime.Now);
		}

		private void form_main_Load(object sender, EventArgs e) {

			// this inits the LoggerObj
			MainObj.SplashShow("Starting interface objects", 60);
			FormLog = new form_log();
			FormSettings = new form_settings();

			#region OwnedForms startup states
			if (null != FormSettings) {
				AddOwnedForm(FormSettings);
				FormSettings.Owner = this;
				if (Properties.Settings.Default.UserSettingsFormVisible) this.SettingsVisibleToggle();
			}
			if (null != FormLog) {
				AddOwnedForm(FormLog);
				FormLog.Owner = this;
				FormLog.Show();
				if (!Properties.Settings.Default.UserLogFormVisible)
					this.LogVisibleToggle();

			}
			#endregion OwnedForms startup states

			
			


			Application.DoEvents();

			MainObj.SplashShow("User interface loaded", 75);

			// Check
			MainObj.SplashShow("Starting network", 80);
			MainObj.NetworkHelper.Init(false,
				MainObj.OdsMain.Settings.PubIPCheckUrl,
				MainObj.OdsMain.Settings.PubIPCheckRegEx,
				MainObj.OdsMain.Settings.ServerAddress,
				MainObj.OdsMain.Settings.ServerPortNumber);
			// check server connectivity
			StartDetectServerConectivity();

			MainObj.SplashShow("Starting network events", 82);
			// network events
			MainObj.NetworkHelper.NetworkAddressChanged = new NetworkHelperObj.NetworkAddressChangedDelegate(NetworkAddressChanged);
			MainObj.NetworkHelper.NetworkAvailabilityChanged = new NetworkHelperObj.NetworkAvailabilityChangedDelegate(netAvailabilityChanged);
			//MainObj.NetworkEventsThreadStart();

			//detecting pub ip
			MainObj.SplashShow("Detecting public IP", 84);
			StartDetectAndReloadMyIPList();

			// auto update by apptimer
			if (MainObj.OdsMain.Settings.UpdateMethod == OdsUpdateMethod.ApplicationTimer) {
				MainObj.SplashShow("Starting the AutoUpdate loop", 87);
				AutoUpdateRefreshState();
			}

			MainObj.SplashShow("Checking service", 90);
			if (MainObj.AppServiceInstalled && MainObj.OdsMain.Settings.UpdateMethod == OdsUpdateMethod.WindowsServiceTimer) {
				MainObj.ServiceInit();
				MainObj.ServiceCheck(true);
			}

			//loads the hosts combo, the ips has already been loaded
			LoadHostsComboBox();


			//Console - startup state
			if (Properties.Settings.Default.UserConsoleVisible) ConsoleToggle();
			MainObj.SplashShow("Checking service", 90);


			SetStatusMessage("Welcome!");
			ReloadStatusBarInfo(false);
			MainObj.SplashHide();
		}
		private void form_main_Activated(object sender, EventArgs e) {
			Console.WriteLine("MainForm Activated");

		}
		int xdelta, ydelta;
		Point _lastLocation;
		private void form_main_Move(object sender, EventArgs e) {
			if (WindowState == FormWindowState.Minimized) return;

			xdelta = this.Location.X - _lastLocation.X;
			ydelta = this.Location.Y - _lastLocation.Y;

			// move log form
			if (null != FormLog && FormLog.Docked && FormLog.DockedToFormName == this.Name) {
				FormLog.Location = new Point(FormLog.Location.X + xdelta, FormLog.Location.Y + ydelta);
			}
			// move settings wind
			if (null != FormSettings && FormSettings.Docked && FormSettings.DockedToFormName == this.Name) {
				FormSettings.Location = new Point(FormSettings.Location.X + xdelta, FormSettings.Location.Y + ydelta); ;
			}
			_lastLocation = Location;
		}
		private void form_main_FormClosing(object sender, FormClosingEventArgs e) {
			MainObj.AppExiting = true;
			SaveUserSettings();
		}
		private void form_main_Resize(object sender, EventArgs e) {
			if (WindowState == FormWindowState.Minimized) {
				this.MinimizeToTray();
				ShowInTaskbar = false;
				notifyIcon1.ShowBalloonTip(5, MainObj.AppName + " minimized to tray", "The application window was minimized to this Tray Icon, Double-Click on it to show the window, ou Right-Click fom more options.", ToolTipIcon.Info);
			} else { // does not allow maximize
				ShowInTaskbar = true;
			}
		}
		#endregion FormEvents

		#region MainInterface
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Show/Hide console
		/// </summary>
		public void ConsoleToggle() {
			if (MainObj.ConsoleVisible) {
				//if (null == FormSettings) {
				//FormSettings = new form_settings();
				//FormSettings.Owner = this;
				//}
				MainObj.ConsoleVisible = false;
				Height = _normalHeight;
			} else {
				MainObj.ConsoleVisible = true;
				Height = _expandedHeight;
				if (!MainObj.LogVisible) this.LogVisibleToggle();
			}
			UpdateToolbarButtons();
		}
		//--------------------------------------------------------------------------------------------
		public delegate void LogVisibleToggleDelegate();
		/// <summary>
		/// Toggles the Log Window's visibility state
		/// </summary>
		public void LogVisibleToggle() {
			if (FormLog.InvokeRequired) {
				Invoke(new LogVisibleToggleDelegate(LogVisibleToggle));
			} else {
				if (!MainObj.LogVisible) {
					MainObj.LogVisible = true;
					FormLog.Show();
					FormLog.BringToFront();
				} else {
					MainObj.LogVisible = false;
					FormLog.Hide();
				}
			}
			UpdateToolbarButtons();
		}
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Toggles the Settings window visibility
		/// </summary>
		public void SettingsVisibleToggle() {
			if (!MainObj.SettingsVisible) {
				//if (null == FormSettings) {
				//FormSettings = new form_settings();
				//FormSettings.Owner = this;
				//}
				MainObj.SettingsVisible = true;
				FormSettings.Show();
				FormSettings.BringToFront();
			} else {
				MainObj.SettingsVisible = false;
				FormSettings.Hide();
			}
			UpdateToolbarButtons();
		}
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Hides the application windows minimizing them to the system tray
		/// </summary>
		public void MinimizeToTray() {
			// if the user has not disabled animating windows...
			if (!MainObj.AnimationDisabled) {

				Win32Helper.RECT animateFrom = new Win32Helper.RECT();

				Win32Helper.GetWindowRect(this.Handle, ref animateFrom);

				Win32Helper.RECT animateTo = new Win32Helper.RECT();
				IntPtr notifyAreaHandle = Win32Helper.GetNotificationAreaHandle();

				if (notifyAreaHandle != IntPtr.Zero) {
					if (Win32Helper.GetWindowRect(notifyAreaHandle, ref animateTo) == true) {
						Win32Helper.DrawAnimatedRects(this.Handle, Win32Helper.IDANI_CAPTION, ref animateFrom, ref animateTo);
					}
				}
			}
		}
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Restores the application windows from the system tray
		/// </summary>
		private void RestoreFromTray() {
			//ShowInTaskbar = true;
			WindowState = FormWindowState.Normal;
			//if (this.Visible == false) {
			//  if (MainObj.LogVisible) FormLog.Visible = true;
			//  if (MainObj.SettingsVisible) FormSettings.Visible = true;

			//  WindowState = FormWindowState.Normal;
			//  this.Visible = true;
			//  this.BringToFront();
			//  this.Activate();
			//} else {
			//  WindowState = FormWindowState.Minimized;
			//  Close();
			//}
			////if (this.WindowState == FormWindowState.Minimized)
			////  this.WindowState = FormWindowState.Normal;
		}
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Changes between minimized to tray and visible/restored
		/// </summary>
		public void ToggleVisible() {
			if (WindowState == FormWindowState.Minimized)
				RestoreFromTray();
			else {
				WindowState = FormWindowState.Minimized;
			}
		}
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Saves the user application settings
		/// </summary>
		public void SaveUserSettings() {
			// TODO shouldn't be there more properties?
			Properties.Settings.Default.UserConsoleVisible = MainObj.ConsoleVisible;
			Properties.Settings.Default.Save();
		}
		//--------------------------------------------------------------------------------------------
		public delegate void LoadMyIPsComboBoxDelegate();
		/// <summary>
		/// Loads the myIPs combobox
		/// </summary>
		public void LoadMyIPsComboBox() {
			if (InvokeRequired) {
				Invoke(new LoadMyIPsComboBoxDelegate(LoadMyIPsComboBox));
			} else {
				cmbMyIps.Items.Clear();

				if (MainObj.NetworkHelper.GetPubIPAddress(false) != null)
					cmbMyIps.Items.Add(MainObj.NetworkHelper.GetPubIPAddress(false).ToString() + " (Detected public ip)");

				IPAddress[] ips = MainObj.NetworkHelper.GetIPAddresses(false);
				for (int i = 0; i < ips.Length; i++) {
					// TODO: add regex to control valid or public ips, add a parameter to define what should be seen
					cmbMyIps.Items.Add(ips[i].ToString());
				}
				if (cmbMyIps.Items.Count > 0) cmbMyIps.SelectedIndex = 0;
			}
		}
		//--------------------------------------------------------------------------------------------
		public delegate void LoadHostsComboBoxDelegate();
		/// <summary>
		/// Loads the hosts combobox
		/// </summary>
		public void LoadHostsComboBox() {
			if (InvokeRequired) {
				Invoke(new LoadHostsComboBoxDelegate(LoadHostsComboBox));
			} else {
				cmbMyHosts.Items.Clear();
				if (null != MainObj.OdsMain && MainObj.OdsMain.Hosts.Count > 0) {
					foreach (OdsHostObj ohost in MainObj.OdsMain.Hosts) {
						cmbMyHosts.Items.Add(ohost.HostName + " - " + ohost.HostType);
					}
					if (cmbMyHosts.Items.Count > 0) cmbMyHosts.SelectedIndex = 0;
				}
			}
		}
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Updates the toolbar buttons checked prop based on the MainObj.LogVisible, MainObj.Settings and MainObj.Console
		/// </summary>
		public void UpdateToolbarButtons() {
			tsbtShowLog.Checked = MainObj.LogVisible;
			tsbtShowSettings.Checked = MainObj.SettingsVisible;
			tsbtShowConsole.Checked = MainObj.ConsoleVisible;
		}
		//--------------------------------------------------------------------------------------------
		public void UpdateAll() {
			WaitCallback myCallback = new WaitCallback(UpdateAllHost);
			ThreadPool.QueueUserWorkItem(myCallback);
		}

		#region MainFormStatusMethods
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Refreshes the status bar info: userStatus and ActiveHostsCount
		/// Resets
		/// </summary>
		public void ReloadStatusBarInfo(bool resetStatusMessage) {
			RefreshStatusBarUserAndOnlineStatus();
			RefreshStatusBarHostsActiveCount();
			if (resetStatusMessage) SetStatusMessage("Ready");
		}
		//--------------------------------------------------------------------------------------------
		public delegate DialogResult ShowMessageBoxDelegate(string msg, string caption, MessageBoxButtons buttons, MessageBoxIcon icon);
		/// <summary>
		/// Show a thread safe modal dialog
		/// </summary>
		/// <param name="msg">Message text</param>
		/// <param name="caption">Caption text</param>
		/// <param name="buttons">Button layout</param>
		/// <param name="icon">Icon to show</param>
		/// <returns>DialogResult selected</returns>
		public DialogResult ShowMessageBox(string msg, string caption, MessageBoxButtons buttons, MessageBoxIcon icon) {
			if (InvokeRequired) {
				return (DialogResult)Invoke(new ShowMessageBoxDelegate(ShowMessageBox), new object[] { msg, caption, buttons, icon });
			} else {
				return MessageBox.Show(this, msg, caption, buttons, icon);
			}
		}
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Show a thread safe modal MainForm dialog MessageBox 
		/// With the Applications name on the caption bar
		/// Thread Safe
		/// </summary>
		/// <param name="msg">Message text</param>
		/// <param name="buttons">Button layout</param>
		/// <param name="icon">Icon to show</param>
		/// <returns>DialogResult selected</returns>
		public DialogResult ShowMessageBox(string msg, MessageBoxButtons buttons, MessageBoxIcon icon) {
			return MessageBox.Show(this, msg, MainObj.AppName, buttons, icon);
		}
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Show a thread safe modal MainForm dialog MessageBox 
		/// With the Applications name on the caption bar, MessageBoxButtons.OK and MessageBoxIcon.Information
		/// Thread Safe
		/// </summary>
		/// <param name="msg">Message text</param>
		/// <param name="buttons">Button layout</param>
		/// <param name="icon">Icon to show</param>
		/// <returns>DialogResult selected</returns>
		public DialogResult ShowMessageBox(string msg) {
			return MessageBox.Show(this, msg, MainObj.AppName, MessageBoxButtons.OK, MessageBoxIcon.Information);
		}
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Shows/Updates the status bar text and progress (disabling the progressbar)
		/// Thread Safe
		/// </summary>
		/// <param name="msg">the msg to show on the statusbar</param>
		public void SetStatusMessage(string msg) {
			SetStatusMessage(msg, -1);
		}
		public delegate void SetStatusMessageDelegate(string msg, int progress);

		/// <summary>
		/// Shows/Updates the status bar text and progress
		/// Thread Safe
		/// </summary>
		/// <param name="msg">the msg to show on the statusbar</param>
		/// <param name="progress">less than 0 removes progress bar, more than 500 uses cycle bar</param>
		public void SetStatusMessage(string msg, int progress) {
			if (sbsMain.InvokeRequired) {
				Invoke(new SetStatusMessageDelegate(SetStatusMessage), new object[] { msg, progress });
			} else {
				sbsMainLabelMessage.Text = msg;
				if (progress >= 500) {
					sbsMainProgress.Width = 65;
					sbsMainProgress.Style = ProgressBarStyle.Marquee;
				} else {
					if (progress < 0) {
						//sbsMainProgress.Visible = false;
						sbsMainProgress.Width = 0;
						sbsMainProgress.Value = 0;
					} else {
						sbsMainProgress.Style = ProgressBarStyle.Blocks;
						if (progress > 100) progress = 100;
						sbsMainProgress.Value = progress;
						sbsMainProgress.Width = 65;
						//sbsMainProgress.Visible = true;
					}
				}
				Refresh();
			}
		}
		//--------------------------------------------------------------------------------------------
		public delegate void RefreshStatusBarUserAndOnlineStatusDelegate();
		/// <summary>
		/// refreshes the user and online status shown on the main window's status bar
		/// Thread Safe
		/// </summary>
		public void RefreshStatusBarUserAndOnlineStatus() {//, bool online){
			if (sbsMain.InvokeRequired) {
				Invoke(new RefreshStatusBarUserAndOnlineStatusDelegate(RefreshStatusBarUserAndOnlineStatus));
			} else {
				string username;
				if (string.IsNullOrEmpty(MainObj.OdsMain.Settings.ServerUsername)) {
					username = "no user";
				} else {
					username = MainObj.OdsMain.Settings.ServerUsername;
				}
				sbsMainLabelStatus.Text = username + " " + (MainObj.NetworkHelper.GetOnline(false) ? "(Online)" : "(Offline)");
			}
		}
		//--------------------------------------------------------------------------------------------
		public delegate void RefreshStatusBarHostsActiveCountDelegate();
		/// <summary>
		/// refreshes the active hosts count shown on the main window's status bar
		/// Thread Safe
		/// </summary>
		public void RefreshStatusBarHostsActiveCount() {
			if (sbsMain.InvokeRequired) {
				Invoke(new RefreshStatusBarHostsActiveCountDelegate(RefreshStatusBarHostsActiveCount));
			} else {
				if (MainObj.OdsMain.Hosts.CountActive > 0) {
					sbsMainLabelHostCount.Visible = true;
					sbsMainLabelHostCount.Text = MainObj.OdsMain.Hosts.CountActive.ToString() + " Active " + (MainObj.OdsMain.Hosts.CountActive > 1 ? "Hosts" : "Host");
				} else
					sbsMainLabelHostCount.Visible = false;
			}
		}
		//--------------------------------------------------------------------------------------------
		#endregion MainFormStatusMethods

		#endregion MainInterface

		#region IPs and networkstate
		/// <summary>
		/// starts in another thread: checks if we can connect to the ods update server
		/// </summary>
		public void StartDetectServerConectivity() {
			if (null == DetectServerConnectivityThread)
				DetectServerConnectivityThread = new Thread(new ThreadStart(DetectServerConectivity));
			else {
				if (DetectServerConnectivityThread.IsAlive) {
					Console.WriteLine("Wainting for the last DetectServerConnectivityThread' thread to finish");
					DetectServerConnectivityThread.Join();
				}
			}

			DetectServerConnectivityThread.Name = "DetectServerConnectivityThread";
			DetectServerConnectivityThread.Start();

			//WaitCallback myCallback = new WaitCallback(DetectServerConectivity);
			//ThreadPool.QueueUserWorkItem(myCallback, null);
		}
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Controls MainObj.AppOnline - checks if we can connect to the ods update server
		/// </summary>
		/// <param name="o">null </param>
		private void DetectServerConectivity() {
			//if (Thread.CurrentThread.IsThreadPoolThread)
			//  Thread.CurrentThread.Name = "DetectServerConectivity";
			// detect pub ip using webservice
			SetStatusMessage("Checking server connection...");
			this.LogWrite("Checking server connection...", LogCategories.ApplicationEvents, DateTime.Now);

			MainObj.NetworkHelper.GetOnline(true);

			SetStatusMessage("Ready");
			RefreshStatusBarUserAndOnlineStatus();

			//// check to see if we can still contact the ods update service
			//bool online = MainObj.NetworkHelper.CheckServerConnection(MainObj.OdsMain.Settings.ServerAddress, MainObj.OdsMain.Settings.ServerPortNumber);
			//if (MainObj.AppOnline != online) {
			//  MainObj.AppOnline = online;

			//  if(MainObj.AppOnline)
			//    MainObj.LogWrite("Server connection ok.", LogCategories.ApplicationEvents, DateTime.Now);
			//  else
			//    MainObj.LogWrite("Server connection lost.", LogCategories.ApplicationEvents, DateTime.Now);

			//  SetStatusMessage("Ready");
			//  ReloadStatusBarInfo();
			//}
			//if (Thread.CurrentThread.IsThreadPoolThread)
			//  Thread.CurrentThread.Name = MainObj.AppName + "ThreadPool";
		}
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Starts in another thread to detect the public ip and reloads the my ips combobox
		/// </summary>
		public void StartDetectAndReloadMyIPList() {
			if (null == DetectPubIPThread)
				DetectPubIPThread = new Thread(new ThreadStart(DetectAndReloadMyIPList));
			else {
				if (DetectPubIPThread.IsAlive) {
					Console.WriteLine("Wainting for the last StartDetectAndReloadMyIPList' thread to finish");
					DetectPubIPThread.Join();
				}
			}

			DetectPubIPThread.Name = "DetectPubIPThread";
			DetectPubIPThread.Start();

			//WaitCallback myCallback = new WaitCallback(DetectAndReloadMyIPList);
			//ThreadPool.QueueUserWorkItem(myCallback, null);
		}
		//--------------------------------------------------------------------------------------------
		/// <summary>
		/// Detects the public ip and reloads the my ips combobox
		/// </summary>
		/// <param name="o">null</param>
		private void DetectAndReloadMyIPList() {
			if (Thread.CurrentThread.IsThreadPoolThread)
				Thread.CurrentThread.Name = "DetectAndReloadMyIPList";

			// detect pub ip using webservice
			SetStatusMessage("Detecting public IP...");
			MainObj.NetworkHelper.GetPubIPAddress(true);
			SetStatusMessage("Detecting public all ip addresses...");
			MainObj.NetworkHelper.GetIPAddresses(true);
			//string pubip = MainObj.NetworkHelper.RetrievePubIpFromURL(MainObj.PubIPCheckUrl, MainObj.PubIPCheckRegEx);
			//if (pubip != String.Empty && pubip != "0.0.0.0") {
			//  MainObj.PubIP = IPAddress.Parse(pubip);
			//  SetStatusMessage("Public IP detected.");
			//} else {
			//  MainObj.PubIP = null;
			//  SetStatusMessage("Public IP could not be detected.");
			//}
			LoadMyIPsComboBox();
		}
		//--------------------------------------------------------------------------------------------
		#endregion IPs and networkstate

		#region MainButtons CallBacks
		//--------------------------------------------------------------------------------------------
		private void CheckHost(object o) {
			//if (null == MainObj.NetworkHelper.GetPubIPAddress(false)) {
			//  MessageBox.Show("You can only check Hosts after you public ip has been detected. Please wait.", Text, MessageBoxButtons.OK, MessageBoxIcon.Stop);
			//  return;
			//}


			HostUpdateInfo hostInfo = o as HostUpdateInfo;
			if (null == hostInfo)
				return;
			int index = hostInfo.HostIndex;

			// if the hosts uses connip this should be the pub ip
			string ip = hostInfo.IP;

			SetStatusMessage("Checking host...", 500);

			try {
				OdsHostObj ohost = MainObj.OdsMain.Hosts[index];
				OdsClientObj myclient = new OdsClientObj(MainObj.OdsMain.Settings, MainObj.OdsMain.Log);

				if (null == ohost) return; //TODO
				string resolvedIp;
				myclient.CheckHost(ref ohost, ip, out resolvedIp);

				SetStatusMessage("Checking host...", -1);

				if (ohost.DnsState == OdsHostDnsState.Unknown) {
					SetStatusMessage("Error checking host");
					return;
				} else if (ohost.DnsState == OdsHostDnsState.DnsMatch) {
					//((MessageBox.Show("Host matches IP.\n\nResolved IP: " + MainObj.PubIP.ToString(), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
					ShowMessageBox("Host matches target IP.\n\nResolved IP: " + resolvedIp, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
				} else if (ohost.DnsState == OdsHostDnsState.DnsNoMatch) {
					if (ShowMessageBox("Host doesn't match target IP.\n\nIf it was updated recently you should wait a few minutes.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.Yes) {
						System.EventArgs ex = new System.EventArgs();
						btUpdateHost_Click(btUpdateHost, ex);
					}

				} else if (ohost.DnsState == OdsHostDnsState.NoDnsEntry) {
					if (ShowMessageBox("Host doesn't have a dns record.\n\nIf it was updated recently you should wait a few minutes.", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.Yes) {
						System.EventArgs ex = new System.EventArgs();
						btUpdateHost_Click(btUpdateHost, ex);
					}
				}
			} catch (OdsClientException odse) {
				if (null != odse.InnerException)
					ShowMessageBox(odse.Message + "\n\n" + odse.InnerException.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
				else
					ShowMessageBox(odse.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			SetStatusMessage("Ready");
		}
		//--------------------------------------------------------------------------------------------
		private void UpdateHost(object o) {
			SetStatusMessage("Updating host...", 500);

			int index = Convert.ToInt32(o);

			if (MainObj.OdsMain.Hosts.Count > 0) {
				try {
					using (OdsClientObj myclient = new OdsClientObj(MainObj.OdsMain.Settings, MainObj.OdsMain.Log)) {

						try {
							myclient.UpdateHost(MainObj.OdsMain.Hosts[index], true);
						} catch (OdsClientException odse) {
							if (null != odse.InnerException)
								ShowMessageBox(odse.Message + "\n\n" + odse.InnerException.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
							else
								ShowMessageBox(odse.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
						}
					}
				} catch (OdsClientException odse) {
					if (null != odse.InnerException)
						ShowMessageBox(odse.Message + "\n\n" + odse.InnerException.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
					else
						ShowMessageBox(odse.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}
			SetStatusMessage("Ready");
		}
		//--------------------------------------------------------------------------------------------
		private void UpdateAllHost(object o) {
			SetStatusMessage("Updating all hosts...", 500);

			if (MainObj.OdsMain.Hosts.Count > 0) {
				try {
					using (OdsClientObj myclient = new OdsClientObj(MainObj.OdsMain.Settings, MainObj.OdsMain.Log)) {
						foreach (OdsHostObj ohost in MainObj.OdsMain.Hosts) {
							if (!ohost.Active) continue;
							if (ohost.HostType != "A" && ohost.HostType != "AAAA") {
								continue;
							}
							try {
								myclient.Connect();
								myclient.Login();
								myclient.UpdateHost(ohost, false);
							} catch (OdsClientException odse) {
								if (null != odse.InnerException)
									ShowMessageBox(odse.Message + "\n\n" + odse.InnerException.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
								else
									ShowMessageBox(odse.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
							}
						}
						myclient.Disconnect();
					}
				} catch (OdsClientException odse) {
					if (null != odse.InnerException)
						ShowMessageBox(odse.Message + "\n\n" + odse.InnerException.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
					else
						ShowMessageBox(odse.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}

			SetStatusMessage("Ready");
		}
		//--------------------------------------------------------------------------------------------
		private void CheckAllHosts(object o) {
			SetStatusMessage("Checking all hosts...", 500);

			bool anyToUpdate = false;

			if (MainObj.OdsMain.Hosts.Count > 0) {
				try {
					using (OdsClientObj myclient = new OdsClientObj(MainObj.OdsMain.Settings, MainObj.OdsMain.Log)) {
						for (int i = 0; i < MainObj.OdsMain.Hosts.Count; i++) {
							// we only check A or AAAA records
							if (MainObj.OdsMain.Hosts[i].HostType != "A" && MainObj.OdsMain.Hosts[i].HostType != "AAAA")
								continue;

							OdsHostObj ohost = MainObj.OdsMain.Hosts[i];

							try {
								myclient.Connect();
								myclient.Login();
								string resolvedIP;
								myclient.CheckHost(ref ohost, MainObj.NetworkHelper.GetPubIPAddress(false).ToString(), out resolvedIP);
								if (ohost.DnsState != OdsHostDnsState.DnsMatch) anyToUpdate = true;
							} catch (OdsClientException odse) {
								if (null != odse.InnerException)
									ShowMessageBox(odse.Message + "\n\n" + odse.InnerException.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
								else
									ShowMessageBox(odse.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
							}
						}
						myclient.Disconnect();
					}
				} catch (OdsClientException odse) {
					if (null != odse.InnerException)
						ShowMessageBox(odse.Message + "\n\n" + odse.InnerException.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
					else
						ShowMessageBox(odse.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
				}
			}

			SetStatusMessage("Ready");

			if (anyToUpdate)
				ShowMessageBox("At least one host needs updating, check the log window.", Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
			else
				ShowMessageBox("All hosts OK.", Text, MessageBoxButtons.OK, MessageBoxIcon.Information);

		}

		//--------------------------------------------------------------------------------------------
		#endregion MainButtons CallBacks

		#region ControlEvents

		#region toolbar
		//--------------------------------------------------------------------------------------------
		private void tsbtShowLog_Click(object sender, EventArgs e) {
			this.LogVisibleToggle();
		}
		//--------------------------------------------------------------------------------------------
		private void tsbtShowSettings_Click(object sender, EventArgs e) {
			this.SettingsVisibleToggle();
		}
		//--------------------------------------------------------------------------------------------
		private void aboutToolStripMenuItem_Click(object sender, EventArgs e) {
			form_about fabout = new form_about();
			fabout.ShowDialog();
		}
		//--------------------------------------------------------------------------------------------
		private void tsbtShowConsole_Click(object sender, EventArgs e) {
			ConsoleToggle();
		}
		//--------------------------------------------------------------------------------------------
		#endregion toolbar

		#region Main Buttons
		//--------------------------------------------------------------------------------------------
		private void btUpdateHost_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;
			if (cmbMyHosts.SelectedIndex < 0) return;

			if (MainObj.OdsMain.Hosts[cmbMyHosts.SelectedIndex].HostType != "A" && MainObj.OdsMain.Hosts[cmbMyHosts.SelectedIndex].HostType != "AAAA") {
				ShowMessageBox("Cannot update this type of host. Only A and AAAA.", "Invalid action on host", MessageBoxButtons.OK, MessageBoxIcon.Stop);
				return;
			}

			WaitCallback myCallback = new WaitCallback(UpdateHost);
			ThreadPool.QueueUserWorkItem(myCallback, cmbMyHosts.SelectedIndex);
		}
		//--------------------------------------------------------------------------------------------
		private void btCheckHost_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;
			if (cmbMyHosts.SelectedIndex < 0) return;

			if (MainObj.OdsMain.Hosts[cmbMyHosts.SelectedIndex].HostType != "A" && MainObj.OdsMain.Hosts[cmbMyHosts.SelectedIndex].HostType != "AAAA") {
				ShowMessageBox("Cannot check this type of host. Only A and AAAA.", "Invalid action on host", MessageBoxButtons.OK, MessageBoxIcon.Stop);
				return;
			}

			//		if (MainObj.OdsMainObj.Hosts[cmbMyHosts.SelectedIndex].UseConnip) {
			string selectedip = cmbMyIps.SelectedItem.ToString();
			if (selectedip.IndexOf(" ") >= 0) selectedip = selectedip.Substring(0, selectedip.IndexOf(" "));

			WaitCallback myCallback = new WaitCallback(CheckHost);
			ThreadPool.QueueUserWorkItem(myCallback, new HostUpdateInfo(cmbMyHosts.SelectedIndex, selectedip));
		}
		//--------------------------------------------------------------------------------------------
		private void btUpdateAllHosts_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;
			if (cmbMyHosts.Items.Count <= 0) return;
			UpdateAll();
		}
		//--------------------------------------------------------------------------------------------
		private void btCheckAllHosts_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;
			if (cmbMyHosts.Items.Count <= 0) return;

			WaitCallback myCallback = new WaitCallback(CheckAllHosts);
			ThreadPool.QueueUserWorkItem(myCallback, null);
		}
		//--------------------------------------------------------------------------------------------
		private class HostUpdateInfo {
			public int HostIndex;
			public string IP;

			public HostUpdateInfo(int hostindex, string ip) {
				HostIndex = hostindex;
				IP = ip;
			}
		}
		//--------------------------------------------------------------------------------------------
		#endregion Main Buttons

		#endregion ControlEvents

		#region TrayIcon
		private void notifyIcon1_DoubleClick(object sender, EventArgs e) {
			ToggleVisible();
		}

		private void showmainwindowToolStripMenuItem_Click(object sender, EventArgs e) {
			ToggleVisible();
		}

		private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
			Close();
		}

		private void ctxNIcon_Opening(object sender, CancelEventArgs e) {
			if (WindowState != FormWindowState.Minimized)
				showmainwindowToolStripMenuItem.Text = "Hide main window";
			else
				showmainwindowToolStripMenuItem.Text = "Show main window";
		}

		#endregion TrayIcon

		public bool CheckAppOnline(bool quiet) {
			if (!MainObj.NetworkHelper.GetOnline(false)) {
				if (!quiet) ShowMessageBox("Working offline, cannot connect to the ODS update server. Please try again later.", "Offline", MessageBoxButtons.OK, MessageBoxIcon.Stop);
				return false;
			}
			return true;
		}

		#region Console
		//--------------------------------------------------------------------------------------------
		internal class SendCommandArguments {
			public string Cmd;
			public bool LoginNotRequired;
			public SendCommandArguments(string cmd, bool loginreq) {
				Cmd = cmd;
				LoginNotRequired = loginreq;
			}
		}
		//--------------------------------------------------------------------------------------------
		OdsClientObj _consoleOdsClient;// = new OdsClientObj(MainObj.OdsMain.Settings, MainObj.Logger);
		//--------------------------------------------------------------------------------------------
		private void ConsoleCmdExecute(object o) {
			SendCommandArguments sendArgs = o as SendCommandArguments;
			if (null == sendArgs) return;

			SetStatusMessage("Executing command: " + sendArgs.Cmd, 500);

			try {
				OdsClientObj _tmpOdsClient = new OdsClientObj(MainObj.OdsMain.Settings, MainObj.OdsMain.Log);
				_tmpOdsClient.Connect();

				if (!sendArgs.LoginNotRequired) _tmpOdsClient.Login();
				_tmpOdsClient.SendDirectCmd(sendArgs.Cmd, false, sendArgs.LoginNotRequired);

				_tmpOdsClient.Disconnect();

			} catch (OdsClientException odse) {
				if (null != odse.InnerException)
					ShowMessageBox(odse.Message + "\n\n" + odse.InnerException.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
				else
					ShowMessageBox(odse.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			SetStatusMessage("Ready");
			//SendCommandArguments sendArgs = o as SendCommandArguments;
			//if (null == sendArgs) return;

			//SetStatusMessage("Executing command: " + sendArgs.Cmd, 500);

			//try {
			//  if (null == _consoleOdsClient) _consoleOdsClient = new OdsClientObj(MainObj.OdsMain.Settings, MainObj.OdsMain.Log);
			//  _consoleOdsClient.Connect();

			//  if(!sendArgs.LoginNotRequired) _consoleOdsClient.Login();
			//  _consoleOdsClient.SendDirectCmd(sendArgs.Cmd, false, sendArgs.LoginNotRequired);

			//  //_consoleOdsClient.Disconnect();

			//} catch (OdsClientException odse) {
			//  if (null != odse.InnerException)
			//    ShowMessageBox(odse.Message + "\n\n" + odse.InnerException.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
			//  else
			//    ShowMessageBox(odse.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
			//}
			//SetStatusMessage("Ready");
		}
		//--------------------------------------------------------------------------------------------
		private void btConsoleCmdExec_Click(object sender, EventArgs e) { //TODO the online check should be a method
			if (!CheckAppOnline(false)) return;

			if (String.IsNullOrEmpty(txtConsoleCommand.Text)) {
				SetStatusMessage("Invalid command");
				return;
			}

			SendCommandArguments sendArgs = new SendCommandArguments(txtConsoleCommand.Text, false);

			WaitCallback myCallback = new WaitCallback(ConsoleCmdExecute);
			ThreadPool.QueueUserWorkItem(myCallback, sendArgs);
		}
		//--------------------------------------------------------------------------------------------
		private void btConsoleListRecords_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;

			SendCommandArguments sendArgs = new SendCommandArguments("LISTRR", false);

			WaitCallback myCallback = new WaitCallback(ConsoleCmdExecute);
			ThreadPool.QueueUserWorkItem(myCallback, sendArgs);
		}
		//--------------------------------------------------------------------------------------------
		private void btConsoleListDomains_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;

			SendCommandArguments sendArgs = new SendCommandArguments("DOMAINS", false);

			WaitCallback myCallback = new WaitCallback(ConsoleCmdExecute);
			ThreadPool.QueueUserWorkItem(myCallback, sendArgs);
		}
		//--------------------------------------------------------------------------------------------
		private void btConsoleWhoami_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;

			SendCommandArguments sendArgs = new SendCommandArguments("WHOAMI", false);

			WaitCallback myCallback = new WaitCallback(ConsoleCmdExecute);
			ThreadPool.QueueUserWorkItem(myCallback, sendArgs);
		}
		//--------------------------------------------------------------------------------------------
		private void btConsoleHelp_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;

			SendCommandArguments sendArgs = new SendCommandArguments("HELP", false);

			WaitCallback myCallback = new WaitCallback(ConsoleCmdExecute);
			ThreadPool.QueueUserWorkItem(myCallback, sendArgs);
		}
		//--------------------------------------------------------------------------------------------
		private void btConsoleChangePass_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;

			if (string.IsNullOrEmpty(txtConsolePassNew.Text) || string.IsNullOrEmpty(txtConsolePassRetype.Text)) {
				SetStatusMessage("Invalid password");
				return;
			}

			SendCommandArguments sendArgs = new SendCommandArguments("CHPASS " + txtConsolePassNew.Text + " " + txtConsolePassRetype.Text, false);

			WaitCallback myCallback = new WaitCallback(ConsoleCmdExecute);
			ThreadPool.QueueUserWorkItem(myCallback, sendArgs);
		}
		//--------------------------------------------------------------------------------------------
		private void btConsoleAddUser_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;

			if (string.IsNullOrEmpty(txtConsoleAddUserEMail.Text) || string.IsNullOrEmpty(txtConsoleAddUserFName.Text) ||
				string.IsNullOrEmpty(txtConsoleAddUserLName.Text) || string.IsNullOrEmpty(txtConsoleAddUserPass.Text) |
				string.IsNullOrEmpty(txtConsoleAddUserUsername.Text)) {
				SetStatusMessage("Please fill all fields");
				return;
			}

			string cmd = "ADDUSER " + txtConsoleAddUserUsername.Text.Trim() + " " + txtConsoleAddUserPass.Text;
			cmd += " " + txtConsoleAddUserEMail.Text + " " + txtConsoleAddUserFName.Text + " " + txtConsoleAddUserLName.Text;


			SendCommandArguments sendArgs = new SendCommandArguments(cmd, true);

			WaitCallback myCallback = new WaitCallback(ConsoleCmdExecute);
			ThreadPool.QueueUserWorkItem(myCallback, sendArgs);
		}
		//--------------------------------------------------------------------------------------------
		private void btConsoleDelUser_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;

			if (string.IsNullOrEmpty(txtConsoleDelUserUsename.Text) || string.IsNullOrEmpty(txtConsoleDelUserPass.Text)) {
				SetStatusMessage("Please fill all fields");
				return;
			}

			string cmd = "DELUSER " + txtConsoleDelUserUsename.Text.Trim() + " " + txtConsoleDelUserPass.Text;

			SendCommandArguments sendArgs = new SendCommandArguments(cmd, true);

			WaitCallback myCallback = new WaitCallback(ConsoleCmdExecute);
			ThreadPool.QueueUserWorkItem(myCallback, sendArgs);
		}
		//--------------------------------------------------------------------------------------------
		private void btConsoleFingerUser_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;

			if (string.IsNullOrEmpty(txtConsoleFingerUserUsername.Text)) {
				SetStatusMessage("Please fill all fields");
				return;
			}

			string cmd = "FINGER " + txtConsoleFingerUserUsername.Text.Trim();

			SendCommandArguments sendArgs = new SendCommandArguments(cmd, true);

			WaitCallback myCallback = new WaitCallback(ConsoleCmdExecute);
			ThreadPool.QueueUserWorkItem(myCallback, sendArgs);
		}
		//--------------------------------------------------------------------------------------------
		private void btConsoleWhois_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;

			if (string.IsNullOrEmpty(txtConsoleWhoisHostname.Text)) {
				SetStatusMessage("Please fill all fields");
				return;
			}

			string cmd = "WHOIS " + txtConsoleWhoisHostname.Text.Trim();

			SendCommandArguments sendArgs = new SendCommandArguments(cmd, true);

			WaitCallback myCallback = new WaitCallback(ConsoleCmdExecute);
			ThreadPool.QueueUserWorkItem(myCallback, sendArgs);
		}
		//--------------------------------------------------------------------------------------------
		private void btConsoleEmailPass_Click(object sender, EventArgs e) {
			if (!CheckAppOnline(false)) return;

			SendCommandArguments sendArgs = new SendCommandArguments("EMAILPASS " + MainObj.OdsMain.Settings.ServerUsername, true);

			WaitCallback myCallback = new WaitCallback(ConsoleCmdExecute);
			ThreadPool.QueueUserWorkItem(myCallback, sendArgs);
		}
		//--------------------------------------------------------------------------------------------
		#endregion Console

		#region Log
		/// <summary>
		/// Writes a log entry to the main log obj
		/// </summary>
		/// <param name="logentry"></param>
		public void LogWrite(string logentry) {
			LogWrite(logentry, LogCategories.ApplicationEvents, DateTime.Now);
		}
		public void LogWrite(string logentry, LogCategories category, DateTime timestamp) {
			// This window must already been shown when using the rtb
			if (!MainObj.LogVisible) LogVisibleToggle();

			MainObj.OdsMain.Log.Write(logentry, category, timestamp);
		}
		#endregion Log

		#region CheckTimmer

		public Thread AutoUpdateCycleThread;
		/// <summary>
		/// Fires up the AutoUpdate thread
		/// </summary>
		public void AutoUpdateInit() {
			//TODO: 1 check the thread state
			AutoUpdateCycleThread = new Thread(new ThreadStart(AutoUpdateCycle));
			AutoUpdateCycleThread.Name = MainObj.AppName + "AutoUpdate";
			AutoUpdateCycleThread.Start();
		}

		/// <summary>
		/// AppTimer
		/// Re-reads AutoUpdate's application state and acts on it
		/// </summary>
		public void AutoUpdateRefreshState() {
			if (MainObj.OdsMain.Settings.UpdateMethod == OdsUpdateMethod.ApplicationTimer) {
				if (null == AutoUpdateCycleThread || !AutoUpdateCycleThread.IsAlive) {
					AutoUpdateInit();
				} else {
					AutoUpdateCycleThread.Abort();
				}
			} else {
				if (null != AutoUpdateCycleThread && AutoUpdateCycleThread.IsAlive)
					AutoUpdateCycleThread.Abort();
			}
		}

		TimeSpan timeDiff;
		string pubip;
		int interval = -1;
		OdsHostObj tmpHost;
		string resolvedIP;
		/// <summary>
		/// AutoUpdate loop - runs on an thread of it's own
		/// </summary>
		public void AutoUpdateCycle() {
			DateTime lastCheckTime = DateTime.MinValue, now;
			while (!MainObj.AppExiting) {
				if (MainObj.OdsMain.Settings.UpdateMethod != OdsUpdateMethod.ApplicationTimer)
					break;

				// detect interval changes
				if (interval != MainObj.OdsMain.Settings.UpdateInterval * 60 * 1000) {
					LogWrite("AutoUpdate - Timer interval set to " + MainObj.OdsMain.Settings.UpdateInterval.ToString() + " mins", LogCategories.ServiceEvents, DateTime.Now);
					interval = MainObj.OdsMain.Settings.UpdateInterval * 60 * 1000;
				}

				interval = MainObj.OdsMain.Settings.UpdateInterval * 60 * 1000;

        pubip = null != MainObj.NetworkHelper.GetPubIPAddress(true) ? MainObj.NetworkHelper.GetPubIPAddress(false).ToString() : "";
				now = DateTime.Now;
				timeDiff = now.Subtract(lastCheckTime);

				OdsHostsCollectionObj myHosts;

				//hosts refresh
				lock (MainObj.OdsMain.Hosts) {
					myHosts = (OdsHostsCollectionObj)MainObj.OdsMain.Hosts.Clone();
				}

				if ((null == lastCheckTime || timeDiff.TotalMilliseconds >= interval)) {
					lastCheckTime = now;

					if (myHosts.CountActive <= 0) {
						// no active hosts to update
						this.LogWrite("AutoUpdate - No active hosts", LogCategories.ServiceEvents, DateTime.Now);
					} else {
						// ip and network check
						if (NetworkInterface.GetIsNetworkAvailable() && pubip != "") {
							using (OdsClientObj myClient = new OdsClientObj(MainObj.OdsMain.Settings)) {
								try {
									this.LogWrite("AutoUpdate - Checking " + myHosts.CountActive.ToString() + " hosts ...", LogCategories.ServiceEvents, DateTime.Now);
									for (int i = 0; i < myHosts.Count; i++) {
										//foreach (OdsHostObj ohost in myHosts) {
										if (!myHosts[i].Active) continue;
										tmpHost = myHosts[i];
										try {
											myClient.CheckHost(ref tmpHost, pubip, out resolvedIP);
                      switch (myHosts[i].DnsState) {
                        case OdsHostDnsState.DnsNoMatch:
                          myClient.UpdateHost(myHosts[i], true);
                          this.LogWrite("AutoUpdate - - - DNS entry mismatch - Host Updated " + myHosts[i].HostName + "(" + pubip + ")", LogCategories.ServiceEvents, DateTime.Now);
                          break;
                        case OdsHostDnsState.NoDnsEntry:
                          myClient.UpdateHost(myHosts[i], true);
                          this.LogWrite("AutoUpdate - - - No DNS entry found - Host Updated " + myHosts[i].HostName + "(" + pubip + ")", LogCategories.ServiceEvents, DateTime.Now);
                          break;
                        case OdsHostDnsState.DnsMatch:
                          this.LogWrite("AutoUpdate - - - Host up to date " + myHosts[i].HostName + "(" + pubip + ")", LogCategories.ServiceEvents, DateTime.Now);
                          break;
                        default:
                          this.LogWrite("AutoUpdate - - - Unknown erro " + myHosts[i].HostName + "(" + pubip + ")", LogCategories.ServiceEvents, DateTime.Now);
                          break;
                      }

                      //if (myHosts[i].DnsState == OdsHostDnsState.DnsNoMatch) {
                      //  myClient.UpdateHost(myHosts[i], true);
                      //  this.LogWrite("AutoUpdate - - - DNS entry mismatch - Host Updated " + myHosts[i].HostName + "(" + pubip + ")", LogCategories.ServiceEvents, DateTime.Now);
                      //} else if (myHosts[i].DnsState == OdsHostDnsState.NoDnsEntry) {
                      //  myClient.UpdateHost(myHosts[i], true);
                      //  this.LogWrite("AutoUpdate - - - No DNS entry found - Host Updated " + myHosts[i].HostName + "(" + pubip + ")", LogCategories.ServiceEvents, DateTime.Now);
                      //} else if (myHosts[i].DnsState == OdsHostDnsState.DnsMatch) {
                      //  this.LogWrite("AutoUpdate - - - Host up to date " + myHosts[i].HostName + "(" + pubip + ")", LogCategories.ServiceEvents, DateTime.Now);
                      //}
										} catch (OdsClientException odse) {
											if (null != odse.InnerException)
												this.LogWrite(odse.Message + "\n" + odse.InnerException.Message, LogCategories.ServiceEvents, DateTime.Now);
											else
												this.LogWrite(odse.Message, LogCategories.ServiceEvents, DateTime.Now);
										}
									}
									this.LogWrite("AutoUpdate - Done.", LogCategories.ServiceEvents, DateTime.Now);
								} catch (OdsClientException odse) {
									if (null != odse.InnerException)
										this.LogWrite(odse.Message + "\n" + odse.InnerException.Message, LogCategories.ServiceEvents, DateTime.Now);
									else
										this.LogWrite(odse.Message, LogCategories.ServiceEvents, DateTime.Now);
								}
							}
						}
					}
				}
				Thread.Sleep(1000);
			} //while
		}


		#endregion CheckTimmer



	}
}
